From 2d4cb3ed5105b9e281f0e714b15011cae4a4dcbb Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 17 Mar 2017 16:12:11 -0700 Subject: [PATCH] Fix overriding mixing with default features Previously Cargo had a bug where if a crate *without* a default feature was overridden with one that did indeed have a default feature then the default may not end up getting activated by accident. The fix was to avoid returning too quickly hen activating dependencies until after we've inspected and learned about replacements. Closes #3812 --- src/cargo/core/resolver/mod.rs | 9 +++--- tests/overrides.rs | 58 ++++++++++++++++++++++++++++++++++ 2 files changed, 63 insertions(+), 4 deletions(-) diff --git a/src/cargo/core/resolver/mod.rs b/src/cargo/core/resolver/mod.rs index b60ed10e3..4943f6fe2 100644 --- a/src/cargo/core/resolver/mod.rs +++ b/src/cargo/core/resolver/mod.rs @@ -316,15 +316,13 @@ fn activate(cx: &mut Context, candidate.summary.package_id().clone()); } - if cx.flag_activated(&candidate.summary, method) { - return Ok(None); - } + let activated = cx.flag_activated(&candidate.summary, method); let candidate = match candidate.replace { Some(replace) => { cx.resolve_replacements.insert(candidate.summary.package_id().clone(), replace.package_id().clone()); - if cx.flag_activated(&replace, method) { + if cx.flag_activated(&replace, method) && activated { return Ok(None); } trace!("activating {} (replacing {})", replace.package_id(), @@ -332,6 +330,9 @@ fn activate(cx: &mut Context, replace } None => { + if activated { + return Ok(None) + } trace!("activating {}", candidate.summary.package_id()); candidate.summary } diff --git a/tests/overrides.rs b/tests/overrides.rs index a44a9cb41..4095cedf2 100644 --- a/tests/overrides.rs +++ b/tests/overrides.rs @@ -1104,3 +1104,61 @@ warning: path override for crate `foo` has altered the original list of dependencies; the dependency on `bar` was either added or\ ")); } + +#[test] +fn override_with_default_feature() { + Package::new("another", "0.1.0").publish(); + Package::new("another", "0.1.1") + .dep("bar", "0.1") + .publish(); + Package::new("bar", "0.1.0").publish(); + + let p = project("local") + .file("Cargo.toml", r#" + [package] + name = "local" + version = "0.0.1" + authors = [] + + [dependencies] + bar = { path = "bar", default-features = false } + another = "0.1" + another2 = { path = "another2" } + + [replace] + 'bar:0.1.0' = { path = "bar" } + "#) + .file("src/main.rs", r#" + extern crate bar; + + fn main() { + bar::bar(); + } + "#) + .file("bar/Cargo.toml", r#" + [package] + name = "bar" + version = "0.1.0" + authors = [] + + [features] + default = [] + "#) + .file("bar/src/lib.rs", r#" + #[cfg(feature = "default")] + pub fn bar() {} + "#) + .file("another2/Cargo.toml", r#" + [package] + name = "another2" + version = "0.1.0" + authors = [] + + [dependencies] + bar = { version = "0.1", default-features = false } + "#) + .file("another2/src/lib.rs", ""); + + assert_that(p.cargo_process("run"), + execs().with_status(0)); +} -- 2.30.2